﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace OpenFrameworkCore.Controls
{
    /// <summary>
    /// OpenFramework에서 사용하는 Control의 기본 클래스
    /// </summary>
	public abstract class ControlBase : System.Windows.Controls.Control, ZIndexEditable
    {
		/// <summary>
		/// Control을 포함하고 있는 ControlContainerBase
		/// </summary>
		public ControlContainerBase OwnerControlContainer
		{
			get;
			set;
		}

        /// <summary>
        /// Control의 기본 Context
        /// </summary>
        private ControlBaseContext controlContext;
        public virtual ControlBaseContext ControlContext
        {
            get
            {
                return controlContext;
            }
            set
            {
				controlContext = value;

				if (value != null)
					// Binding 초기화
					InitBinding();
				else
					// Binding 제거
					ClearBinding();
            }
        }

        /// <summary>
        /// 그룹에 속한 경우 그룹 ID
        /// </summary>
        private string ownerGroupID;
        public string OwnerGroupID
        {
            get
            {
                return ownerGroupID;
            }
            set
            {
                ownerGroupID = value;
            }
        }


		#region ZIndex Releated Members

		public static readonly DependencyProperty ZIndexProperty = DependencyProperty.Register
			(
			"ZIndex",
			typeof(int),
			typeof(BasicControl),
			new PropertyMetadata(OnZIndexPropertyChanged)
			);

		private static void OnZIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			((BasicControl)d).OnZIndexPropertyChanged(e);
		}

		private void OnZIndexPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			SetValue(Canvas.ZIndexProperty, (int)e.NewValue);
		}

		/// <summary>
		/// ZIndex
		/// </summary>
		public int ZIndex
		{
			get
			{
				return (int)GetValue(ZIndexProperty);
			}

			set
			{
				// throw EditablePropertyLocked exception
				if (ZIndexEditable == false)
					throw new EditableFieldLockedException("ZIndex property can't edit.");

				// Check value whether is less than min value or bigger than max value.
				if (value < ZIndexMin)
					value = ZIndexMin;

				if (value > ZIndexMax)
					value = ZIndexMax;

				SetValue(ZIndexProperty, value);
			}
		}

		/// <summary>
		/// ZIndex 수정 가능 여부
		/// </summary>
		public bool ZIndexEditable
		{
			get
			{
				return (bool)GetValue(ZIndexEditableProperty);
			}
			set
			{
				SetValue(ZIndexEditableProperty, value);
			}
		}

		public static readonly DependencyProperty ZIndexEditableProperty = DependencyProperty.Register
			(
			"ZIndexEditable",
			typeof(bool),
			typeof(BasicControl),
			null
			);

		/// <summary>
		/// ZIndex 최소값
		/// </summary>
		public int ZIndexMin
		{
			get;
			set;
		}

		/// <summary>
		/// ZIndex 최대값
		/// </summary>
		public int ZIndexMax
		{
			get;
			set;
		}

		#endregion


        /// <summary>
        /// 생성자
        /// </summary>
        public ControlBase()
		{
			// 최소, 최대값 설정
			InitMinMaxValue();
        }

		/// <summary>
		/// Binding을 초기화 합니다.
		/// </summary>
		protected virtual void InitBinding()
		{
			// ZIndex binding 설정
			Binding zIndexBinding = new Binding("ZIndex");
			zIndexBinding.Source = ControlContext;
			zIndexBinding.Mode = BindingMode.TwoWay;
			SetBinding(ZIndexProperty, zIndexBinding);
		}

		/// <summary>
		/// Binding을 제거합니다.
		/// </summary>
		protected virtual void ClearBinding()
		{
			ClearValue(OpacityProperty);
		}

		/// <summary>
		/// Min, Max Value 초기화
		/// </summary>
		private void InitMinMaxValue()
		{
			ZIndexEditable = true;
			ZIndexMin = 0;
			ZIndexMax = int.MaxValue;
		}
	}
}